home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / _fixdfsi.cpp < prev    next >
C/C++ Source or Header  |  1992-04-26  |  4KB  |  192 lines

  1. |
  2. |  double float to long conversion routine
  3. |
  4. | M. Ritzert (ritzert@DFG.DBP.DE)
  5.  
  6.     .text
  7.     .even
  8.  
  9. #ifdef ERROR_CHECK
  10.  
  11. _Overflow:
  12.     .ascii "OVERFLOW\0"
  13. _Error_String:
  14.     .ascii "_fixdfsi: %s error\n\0"
  15. .even
  16.  
  17. #endif ERROR_CHECK
  18.  
  19. #ifdef sfp004
  20. |
  21. | 4.10.1990/10.1.1992
  22. |
  23. | addresses of the 68881 data port. This choice is fastest when much data is
  24. | transferred between the two processors.
  25.  
  26. comm =     -6
  27. resp =    -16
  28. zahl =      0
  29.  
  30. | waiting loop ...
  31. |
  32. | wait:
  33. | ww:    cmpiw    #0x8900,a0@(resp)
  34. |     beq    ww
  35. | is coded directly by
  36. |    .long    0x0c688900, 0xfff067f8
  37.  
  38.     .globl    __fixdfsi, ___fixdfsi
  39. __fixdfsi:
  40. ___fixdfsi:
  41.     lea    0xfffa50,a0
  42.     movew    #0x5403,a0@(comm)    | fintrz to fp0
  43.     cmpiw    #0x8900,a0@(resp)    | check
  44.     movel    a7@(4),a0@
  45.     movel    a7@(8),a0@
  46.     movew    #0x6000,a0@(comm)    | result to d0
  47.     .long    0x0c688900, 0xfff067f8
  48.     movel    a0@,d0
  49.         
  50. #endif    sfp004
  51. #ifdef    __M68881__
  52.  
  53. |
  54. | floating point stuff for Atari-gcc using
  55. | an 68030/68881
  56. | developed with gcc/gas
  57. |
  58. | double float to long conversion routine
  59. |
  60. | M. Ritzert (mjr@dfg.dbp.de)
  61. |
  62. | 30.11.1991/10.1.1992
  63. |
  64.  
  65.     .globl    __fixdfsi, ___fixdfsi
  66. __fixdfsi:
  67. ___fixdfsi:
  68.     fintrzd sp@(4),fp0        | convert the arg
  69.     fmovel fp0,d0            | return
  70.  
  71. #endif    __M68881__
  72.  
  73.  
  74. # if !defined (sfp004) && !defined (__M68881__)
  75.  
  76. | double float to long conversion routine
  77. |
  78. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  79. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  80. |
  81. | modified by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de):
  82. | no loop needed for the shift-down case
  83. | testing for far shifts now too slow
  84. | use different registers to gain speed
  85. |
  86. | Revision 1.3, kub 01-90 :
  87. | added support for denormalized numbers
  88. |
  89. | Revision 1.2, kub 01-90 :
  90. | replace far shifts by swaps to gain speed
  91. |
  92. | Revision 1.1, kub 12-89 :
  93. | Ported over to 68k assembler
  94. |
  95. | Revision 1.0:
  96. | original 8088 code from P.S.Housel
  97.  
  98. BIAS8    =    0x3FF-1
  99.  
  100.     .text
  101.     .even
  102.     .globl    __fixdfsi, ___fixdfsi
  103.  
  104. __fixdfsi:
  105. ___fixdfsi:
  106.     lea    sp@(4),a0    | pointer to parameters
  107.     moveml    d2/d3,sp@-    | save registers
  108.     moveml    a0@,d0-d1    | get the number
  109.     movew    a0@,d2        | extract exp
  110.     movew    d2,d3        | extract sign
  111.     lsrw    #4,d2
  112.     andw    #0x07ff,d2    | kill sign bit
  113.  
  114.     andl    #0x0fffff,d0    | remove exponent from mantissa
  115.     orl    #0x100000,d0    | restore implied leading "1"
  116.  
  117.     cmpw    #BIAS8,d2    | check exponent
  118.     blt    zero        | strictly factional, no integer part ?
  119.     cmpw    #BIAS8+32,d2    | is it too big to fit in a 32-bit integer ?
  120.     bgt    toobig
  121.  
  122.     subw    #BIAS8+21,d2    | adjust exponent
  123.     bgt    2f        | shift up
  124.     beq    7f        | no shift (never too big)
  125.  
  126.     negw    d2
  127.     lsrl    d2,d0        | shift down to align radix point;
  128.                 | extra bits fall off the end (no rounding)
  129.     bra    7f        | never too big
  130.  
  131. 2:    addl    d1,d1        | shift up to align radix point
  132.     addxl    d0,d0
  133.     subw    #1,d2
  134.     bgt    2b
  135.  
  136. 3:    cmpl    #0x80000000,d0    | -2147483648 is a nasty evil special case
  137.     bne    6f
  138.     tstw    d3        | this had better be -2^31 and not 2^31
  139.     bpl    toobig
  140.     bra    8f
  141. 6:    tstl    d0        | sign bit set ? (i.e. too big)
  142.     bmi    toobig
  143. 7:
  144.     tstw    d3        | is it negative ?
  145.     bpl    8f
  146.     negl    d0        | negate
  147. 8:
  148.     moveml    sp@+,d2/d3
  149.     rts
  150.  
  151. zero:
  152.     clrl    d0        | make the whole thing zero
  153.     bra    8b
  154.  
  155. toobig:
  156.     movel    #0x7fffffff,d0    | ugh. Should cause a trap here.
  157.  
  158. #endif !defined (sfp004) && !defined (__M68881__)
  159.  
  160. #ifdef    ERROR_CHECK
  161.  
  162. | all three versions
  163.     cmpil    #0x7fffffff,d0    | >= long_max
  164.     bge    error_plus    |
  165.     cmpil    #-0x7fffffff,d0    | <= long_min ?
  166.     ble    error_minus    |
  167.     rts            |
  168. error_minus:
  169.     moveml    d0-d1,a7@-
  170.     movel    #63,_errno    | errno = ERANGE
  171.     pea    _Overflow    | for printf
  172.     bra    error_exit    |
  173. error_plus:
  174.     moveml    d0-d1,a7@-
  175.     movel    #63,_errno    | errno = ERANGE
  176.     pea    _Overflow    | for printf
  177.     bra    error_exit    |
  178.  
  179. error_exit:
  180.     pea    _Error_String    |
  181.     pea    __iob+52    |
  182.     jbsr    _fprintf    |
  183.     addl    #12,a7        |
  184.     moveml    a7@+,d0-d1
  185. #endif    ERROR_CHECK
  186.  
  187. # if !defined (sfp004) && !defined (__M68881__)
  188.     bra    8b
  189. #else
  190.     rts
  191. #endif
  192.